package com.rockymew.core.utility.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import freemarker.log.Logger;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.MultipartBody.Builder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

public class HttpTool {
    public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");

    public enum ContentType {
        JSON("application/json;charset=UTF-8"), XML("application/xml;charset=UTF-8");

        ContentType(String value) {	this.value = value;}
        public String value;
    }

    private static final OkHttpClient client = new OkHttpClient();

    public static String get( String url ) throws HttpConnectionException{
        try {
            //Request request = new Request.Builder().url(url).get().addHeader("Content-Type", "*").build();
            Request request = new Request.Builder().url(url).get().build();
         
            Response response = client.newCall(request).execute();
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            return response.body().string();
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.getMessage());
        }
    }

    public static String get( String url, Map<String, String> params ) throws HttpConnectionException, Exception{
        try {
            //Request request = new Request.Builder().url(url).get().addHeader("Content-Type", "*").build();
            StringBuffer paramExt = new StringBuffer(1000);
            String key =null;
            String value = null;
            if( null != params && params.size() > 0  ){
                boolean bfirst = true;
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if( null != entry.getValue() ){
                        String kv = String.format("%s%s=%s",
                                bfirst ? "" : "&",
                                        URLEncoder.encode(entry.getKey(), "UTF-8"),
                                        URLEncoder.encode(entry.getValue(), "UTF-8"));
                        paramExt.append(  kv  );
                        key =   URLEncoder.encode(entry.getKey(), "UTF-8");
                        value = URLEncoder.encode(entry.getValue(), "UTF-8");
                        bfirst = false;
                    }
                }
            }
            String ext = paramExt.toString();
//            if( !ext.isEmpty() ){
//            	if(url.contains(""))
//                url += /*"?"+*/ext;
//            }
            Logger logger = Logger.getLogger("MyLogger");
			logger.debug(url);
            Request request = new Request.Builder().url(url).addHeader(key, value). get().build();
            
      
          
            Response response = client.newCall(request).execute();
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            return response.body().string();
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.getMessage());
        }
    }

    public static String jsonPost( String url, String content ) throws HttpConnectionException{
        return post(url, content, ContentType.JSON);
    }

    private static String post(String url, String content, ContentType contentType) throws HttpConnectionException{
        MediaType mediaType = MediaType.parse(contentType.value);

        RequestBody body = RequestBody.create(mediaType, content);
        Request request = new Request.Builder().url(url).post(body).build();

        try {
            Response response = client.newCall(request).execute();
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            throw new HttpConnectionException(url, e.getMessage());
        }
    }

    /**
     * 下载文件
     *
     * @param url
     * @return 文件 InputStream
     */
    public static HttpFileInputStream fileGet(String url) throws HttpConnectionException{
        Request request = new Request.Builder().url(url).get().build();
        Response response;
        try {
            response = client.newCall(request).execute();
            
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            
            ResponseBody body = response.body();

            ContentDisposition content_disposition = ContentDisposition.parse(response.header("Content-Disposition"));

            return new HttpFileInputStream( body.byteStream(), body.contentType(), (int)body.contentLength(),
                    content_disposition == null ? null : content_disposition.getFilename());
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.toString());
        }
    }
    
    /**
     * 下载文件
     *
     * @param url
     * @return 文件 InputStream
     */
    public static HttpFileInputStream downloadFileByJsonPost(String url, String content) throws HttpConnectionException{
        
        MediaType mediaType = MediaType.parse(ContentType.JSON.value);

        RequestBody body = RequestBody.create(mediaType, content);
        Request request = new Request.Builder().url(url).post(body).build();
        
        Response response;
        try {
            response = client.newCall(request).execute();
            
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            
            ResponseBody responseBody = response.body();

            ContentDisposition content_disposition = ContentDisposition.parse(response.header("Content-Disposition"));

            return new HttpFileInputStream( responseBody.byteStream(), body.contentType(), (int)body.contentLength(),
                    content_disposition == null ? null : content_disposition.getFilename());
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.toString());
        }
    }

    //通过InputStream上传文件
    private static class InputStreamRequestBody extends RequestBody{
        private InputStream inputStream;
        private MediaType mediaType;

        public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
            return new InputStreamRequestBody(inputStream, mediaType);
        }

        private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
            this.inputStream = inputStream;
            this.mediaType = mediaType;
        }

        @Override
        public MediaType contentType() {
            return this.mediaType;
        }

        @Override
        public long contentLength() {
            try {
                return this.inputStream.available();
            } catch (IOException e) {
                return 0;
            }
        }

        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            Source source = null;
            try {
                source = Okio.source(this.inputStream);
                sink.writeAll(source);
            } finally {
                if( source != null ){
                    Util.closeQuietly(source);
                }
            }
        }
    }

    /**
     * 使用FORM上传
     * @param url
     * @param is
     * @param filename
     * @param name
     * @return
     * @throws HttpConnectionException
     */
    public static String uploadFile(String url, InputStream is, String filename, String name, Map<Object, Object> params) throws HttpConnectionException, Exception {
        Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(name, URLEncoder.encode(filename, "UTF-8"),
                        InputStreamRequestBody.create(MediaType.parse("application/octet-stream"), is));
        if( null != params  ){
            for (Map.Entry<Object, Object> entry : params.entrySet()) {
                builder.addFormDataPart(entry.getKey().toString(), entry.getValue().toString());
            }
        }

        RequestBody requestBody = builder.build();

        Request request = new Request.Builder().url(url).post(requestBody).build();

        Response response;
        try {
            response = client.newCall(request).execute();
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            return response.body().string();
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.toString());
        }
    }


    public static void main(String[] args) throws FileNotFoundException, HttpConnectionException, Exception {
        Map<Object, Object> map = new HashMap<Object, Object>();
        map.put("webinar_id","372604040");
        map.put("account","v13433355");
        map.put("password","rockymew");
        map.put("auth_type","1");
        uploadFile("http://e.vhall.com/api/vhallapi/v2/webinar/activeimage",
                new FileInputStream("E:/workspace/columbus_new/src/logo.png"), "image.png", "image",map);
    }


    public static String uploadFile(String url, InputStream is, String filename, String name) throws HttpConnectionException, Exception {
        return HttpTool.uploadFile(url, is, filename, name, null);
    }
    /**
     * 使用FORM上传
     * @param url
     * @param file
     * @param filename
     * @param name
     * @return
     * @throws HttpConnectionException
     */
    public static String uploadFile(String url, File file, String filename, String name) throws HttpConnectionException, Exception {
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(name, URLEncoder.encode(filename, "UTF-8"),
                        RequestBody.create(MediaType.parse("application/octet-stream"), file))
                .build();

        Request request = new Request.Builder()
                //.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
                .url(url)
                .post(requestBody)
                .build();

        Response response;
        try {
            response = client.newCall(request).execute();
            if( !response.isSuccessful() ){
                throw new HttpConnectionException(url, "http response code is "+response.code());
            }
            return  response.body().string();
        } catch (IOException e) {
            throw new HttpConnectionException(url, e.toString());
        }
    }
}
